package com.celesea.sso.user.controller;

import com.celesea.framework.authority.AuthorityPrincipal;
import com.celesea.framework.jwt.JwtCookieUtil;
import com.celesea.framework.jwt.JwtProperties;
import com.celesea.framework.jwt.JwtRedisUtil;
import com.celesea.framework.jwt.JwtUtil;
import com.celesea.framework.util.StringKit;
import com.celesea.sso.user.controller.request.LoginRequest;
import com.celesea.sso.user.service.UserService;
import com.celesea.sso.user.vo.LoginVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

@Controller
public class LoginController {
    public static final String LOGIN_TEMPLATE = "login_page";
    @Autowired
    private UserService userService;
    @Autowired
    @Qualifier("ssoRedisTemplate")
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private JwtProperties properties;



    @RequestMapping("/")
    public String home() {
        return LOGIN_TEMPLATE;
    }

    @RequestMapping("/login")
    public String login() {
        return LOGIN_TEMPLATE;
    }

    @RequestMapping("/test")
    @ResponseBody
    public String test() {
        return LOGIN_TEMPLATE;
    }


    @RequestMapping(value = "login", method = RequestMethod.POST)
    public String login(HttpServletResponse response, LoginRequest request, Model model) {
        try {
            AuthorityPrincipal userDetails = userService.selectLogin(new LoginVo(request));
            String token = JwtUtil.generateToken(userDetails.getLoginSessionId());
            save2Redis(userDetails);
            JwtCookieUtil.create(response, token, properties.isSecure(),
                    properties.getMaxAge(), properties.getDomain());
            return "redirect:" + request.getRedirect();
        } catch (Exception e) {
            model.addAttribute("error", e.getMessage());
            return LOGIN_TEMPLATE;
        }
    }

    @RequestMapping("logout")
    public String logout(HttpServletRequest request, HttpServletResponse response) {
        JwtCookieUtil.clear(response);
        String loginSessionId = JwtUtil.getSubject(request);
        if (StringKit.isNotEmpty(loginSessionId)) {
            clearRedis(loginSessionId);
        }
        return LOGIN_TEMPLATE;
    }

    private void clearRedis(String loginSessionId) {
        String redisKey = JwtRedisUtil.getInfoKey(loginSessionId);
        redisTemplate.delete(redisKey);
    }

    private void save2Redis(AuthorityPrincipal principal) {
        String redisKey = JwtRedisUtil.getInfoKey(principal.getLoginSessionId());
        redisTemplate.opsForValue().set(redisKey, principal, properties.getMaxAge(), TimeUnit.SECONDS);
    }

}
